package skipManage

import (
	"bufio"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"main/src/apps"
	"main/src/utils"
	"mime/multipart"
	"strconv"
	"time"
)

type CreateSkipDto struct {
	URL string `json:"url"  binding:"required"` // URL
	Cat int    `json:"cat"`                     // 所属品类
}

func (dto *CreateSkipDto) Create(c *gin.Context) (res SkipInfoResponseDto, err error) {
	model := &Skip{
		URL: dto.URL,
		Cat: dto.Cat,
	}
	result := apps.DB.Create(model)
	err = result.Error
	if err != nil {
		utils.Response(
			c,
			"插入失败err: "+err.Error(),
			utils.Status.Error,
			nil,
		)
	} else {
		res.format(*model)
	}
	return res, err
}

type GetSkipDto struct {
	utils.GetDataLimitDto
	Cat string `json:"cat"` // 所属品类
}

func (dto *GetSkipDto) Get(c *gin.Context) (responseDto utils.GetDataLimitResponseDto, err error) {
	dto.Init()
	if dto.PageNum < 0 {
		utils.Response(c, "page_num < 0", utils.Status.Error, nil)
		return responseDto, errors.New("page < 0")
	}
	var models []Skip
	var skips []*SkipInfoResponseDto
	var count int64
	apps.DB.Model(&Skip{}).Count(&count).Limit(dto.PageSize).Offset((dto.PageNum - 1) * dto.PageSize).Find(&models)
	for i := range models {
		temp := &SkipInfoResponseDto{}
		temp.format(models[i])
		skips = append(skips, temp)
	}
	responseDto.Init(dto.GetDataLimitDto, count, skips)
	return responseDto, err
}

type SkipInfoResponseDto struct {
	Id        int       `json:"id"`
	URL       string    `json:"url"` // URL
	Cat       int       `json:"cat"` // 所属品类
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

func (dto *SkipInfoResponseDto) format(model Skip) {
	dto.Id = model.Id
	dto.URL = model.URL
	dto.Cat = model.Cat
	dto.CreatedAt = model.CreatedAt
	dto.UpdatedAt = model.UpdatedAt
}

type UpdateSkipDto struct {
	Id  int    `json:"id"`
	URL string `json:"url"` // 目标 URL
	Cat string `json:"cat"` // 所属品类
}

func (dto *UpdateSkipDto) UpdateContent(c *gin.Context) (ctn SkipInfoResponseDto, err error) {
	skip := &Skip{Id: dto.Id}
	result := apps.DB.Where(skip).Find(&skip)
	if result.Error == nil && len(skip.CreatedAt.String()) > 0 {
		if dto.URL != "" {
			skip.URL = dto.URL
		}
		if dto.Cat != "" {
			skip.Cat, _ = strconv.Atoi(dto.Cat)
		}
		result = apps.DB.Save(&skip)
		err = result.Error
	}
	if err == nil && result.RowsAffected == 0 {
		err = errors.New("该数据以删除，或没有该ID")
	}
	if err != nil {
		utils.Response(
			c,
			"更新失败err: "+err.Error(),
			utils.Status.Error,
			nil,
		)
	} else {
		ctn.format(*skip)
	}
	return ctn, err
}

type DeleteSkipDto struct {
	Id int `json:"id"`
}

func (dto *DeleteSkipDto) Delete(c *gin.Context) (err error) {
	result := apps.DB.Delete(&Skip{Id: dto.Id})
	err = result.Error
	if err != nil {
		utils.Response(
			c,
			"删除失败err: "+err.Error(),
			utils.Status.Error,
			nil,
		)
	}
	return err
}

// CatManager

type CreateCatDto struct {
	Name string `json:"name"  binding:"required"` // 所属品类
}

func (dto *CreateCatDto) Create(c *gin.Context) (res CatInfoResponseDto, err error) {
	model := &Cat{
		Name: dto.Name,
	}
	result := apps.DB.Create(model)
	err = result.Error
	if err != nil {
		utils.Response(
			c,
			"插入失败err: "+err.Error(),
			utils.Status.Error,
			nil,
		)
	} else {
		res.format(*model)
	}
	return res, err
}

type GetCatDto struct {
	utils.GetDataLimitDto
	Name string `json:"name"` // 所属品类
}

func (dto *GetCatDto) Get(c *gin.Context) (responseDto utils.GetDataLimitResponseDto, err error) {
	dto.Init()
	if dto.PageNum < 0 {
		utils.Response(c, "page_num < 0", utils.Status.Error, nil)
		return responseDto, errors.New("page < 0")
	}
	var models []Cat
	var cats []*CatInfoResponseDto
	var count int64
	apps.DB.Limit(dto.PageSize).Offset((dto.PageNum - 1) * dto.PageSize).Find(&models).Limit(-1).Offset(-1).Count(&count)
	for i := range models {
		temp := &CatInfoResponseDto{}
		temp.format(models[i])
		cats = append(cats, temp)
	}
	responseDto.Init(dto.GetDataLimitDto, count, cats)
	return responseDto, err
}

type CatInfoResponseDto struct {
	Id        int       `json:"id"`
	Name      string    `json:"name"` // 所属品类
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

func (dto *CatInfoResponseDto) format(model Cat) {
	dto.Id = model.Id
	dto.Name = model.Name
	dto.CreatedAt = model.CreatedAt
	dto.UpdatedAt = model.UpdatedAt
}

type UpdateCatDto struct {
	Id   int    `json:"id"`
	Name string `json:"name"` // 目标 URL
}

func (dto *UpdateCatDto) UpdateCat(c *gin.Context) (ctn CatInfoResponseDto, err error) {
	cat := &Cat{Id: dto.Id}
	result := apps.DB.Where(cat).Find(&cat)
	if result.Error == nil && len(cat.Name) > 0 {
		if dto.Name != "" {
			cat.Name = dto.Name
		}
		result = apps.DB.Save(&cat)
		err = result.Error
	}
	if err == nil && result.RowsAffected == 0 {
		err = errors.New("该数据以删除，或没有该ID")
	}
	if err != nil {
		utils.Response(
			c,
			"更新失败err: "+err.Error(),
			utils.Status.Error,
			nil,
		)
	} else {
		ctn.format(*cat)
	}
	return ctn, err
}

type DeleteCatDto struct {
	Id int `json:"id"`
}

func (dto *DeleteCatDto) Delete(c *gin.Context) (err error) {
	result := apps.DB.Delete(&Cat{Id: dto.Id})
	err = result.Error
	if err != nil {
		utils.Response(
			c,
			"删除失败err: "+err.Error(),
			utils.Status.Error,
			nil,
		)
	}
	return err
}

type ExportFileBySkip struct {
	File *multipart.FileHeader
	Cat  int `form:"cat"`
}

func (e *ExportFileBySkip) Export(c *gin.Context) (ctn []SkipInfoResponseDto, err error) {
	// 打开文件
	f, err := e.File.Open()
	if err != nil {
		utils.Response(c, fmt.Sprintf("打开文件失败：%s", err.Error()), utils.Status.Error, nil)
		return
	}
	defer f.Close()
	ctn = []SkipInfoResponseDto{}
	// 逐行读取文本内容
	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := scanner.Text()
		skip := Skip{
			URL: line,
			Cat: e.Cat,
		}
		apps.DB.Create(&skip)
		log.Println(line)

	}
	return ctn, err
}
